package ru.ifmo.croak.impl.remoting.query.team3.server;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import ru.ifmo.croak.api.QueryService;
import ru.ifmo.croak.impl.remoting.query.team3.RemoteServer;
import ru.ifmo.croak.impl.remoting.query.team3.RemoteMessageQuery;
import ru.ifmo.croak.impl.remoting.query.team3.ServerQuery;
import ru.ifmo.croak.impl.remoting.query.team3.ServerQueryImpl;
import ru.ifmo.croak.util.CroakFactory;

/**
 * QueryServer main class.
 * <ul>
 * <li>Listens for connections from remote side via TCP/IP server socket.
 * <li>Accepts multiple socket connections.
 * </ul>
 * 
 * @author Arina Afanasyeva
 */
public class QueryServerMain implements Runnable, RemoteServer {
	private final String name;
	private final int port;
	private final QueryService service;

	public QueryServerMain(String name) {
		this.name = name;
		this.port = Integer.parseInt(CroakFactory.getInstance().getProperty(this.name + ".query.port"));

		String queryProviderName = CroakFactory.getInstance().getProperty(name + ".query.provider");
		this.service = CroakFactory.getInstance().getImplementation(QueryService.class,
				queryProviderName);
	}

	@Override
	public void run() {
		try {
            Registry registry = LocateRegistry.createRegistry(port);
            Remote stub = UnicastRemoteObject.exportObject(this, 0);
			registry.rebind("server", stub);
		} catch (RemoteException e) {
			System.out.println("Cannot export object: " + e.getMessage());
			e.printStackTrace();
		}
	}

	/**
	 * Satisfies query by passing to it the {@link QueryService}
	 * specified in the properties file.
	 * 
	 * The service is used to create the actual remote query.
	 *
     * @param query
     *            the query to be satisfied
     */
	public ServerQuery createServerQuery(RemoteMessageQuery query) throws RemoteException {
		ServerQuery sq = new ServerQueryImpl(service, query);
        UnicastRemoteObject.exportObject(sq, 0);
        return sq;
	}

}
